Imports System.Text


Public Class XMLSitemap

    'This is a sitemap library of static functions to generate an xml sitemap for submission to google, yahoo, msn, etc
    'Ian Lintner
    'License: GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
    '7/15/2008

    Public Const XMLTag As String = "<?xml version=""1.0"" encoding=""utf-8"" standalone=""yes""?>"
    Public Const HeaderTag As String = "<urlset xmlns=""http://www.sitemaps.org/schemas/sitemap/0.9"">"
    Public Const ClosingHeaderTag As String = "</urlset>"
    Public Const GroupingTag As String = "url"
    Public Const LocationTag As String = "loc"
    Public Const FrequencyTag As String = "freq"
    Public Const ModifiedTag As String = "lastmod"
    Public Const PriorityTag As String = "priority"

    'Example of sitemap
    '
    '<?xml version="1.0" encoding="utf-8" standalone="yes"?>
    '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    '   <url>
    '       <loc>http://www.mysite.com/home.html</loc>
    '       <lastmod>2008-07-01</lastmod>
    '       <changefreq>Weekly</changefreq>
    '       <priority>1</priority>
    '   </url>
    '</urlset>

    'This is accepts mistakes in the object, if it doesn't find what it needs it just doesn't include it
    Public Shared Function AddSitemapUrl(ByVal SitemapUrl As SitemapUrl) As String
        Dim myStringBuilder As New StringBuilder()

        If SitemapUrl.Location IsNot Nothing AndAlso SitemapUrl.Location <> String.Empty Then
            myStringBuilder.AppendLine(AddIndentedNode(LocationTag, SitemapUrl.Location, 2))

            If Not SitemapUrl.LastUpdated = DateTime.MinValue Then
                'Date Format in sitemaps must be in 2008-01-01 format!
                myStringBuilder.AppendLine(AddIndentedNode(ModifiedTag, Format(SitemapUrl.LastUpdated, "yyyy-MM-dd"), 2))
            End If

            If SitemapUrl.UpdateFrequency IsNot Nothing AndAlso SitemapUrl.UpdateFrequency <> String.Empty Then
                myStringBuilder.AppendLine(AddIndentedNode(FrequencyTag, SitemapUrl.UpdateFrequency, 2))
            End If

            If SitemapUrl.Priority > 0 AndAlso SitemapUrl.Priority <= 1 Then
                myStringBuilder.AppendLine(AddIndentedNode(PriorityTag, SitemapUrl.Priority.ToString, 2))
            End If

            myStringBuilder.AppendLine(String.Empty)

            Return AddIndentedNode(GroupingTag, myStringBuilder.ToString, 1)
        Else
            Return ""
        End If

    End Function


    Public Shared Function AddIndentedNode(ByVal Name As String, ByVal Value As String, ByVal Indent As Integer) As String
        Dim myIndent As String = ""

        For i As Integer = 1 To Indent
            myIndent &= vbTab
        Next

        Return AddNode(Name, Value, myIndent)
    End Function

    Public Shared Function AddNode(ByVal Name As String, ByVal Value As String, Optional ByVal Indent As String = "") As String
        Dim myFormattedValue As String = Value.Replace("&", "&amp;")
        Return Indent & "<" & Name & ">" & myFormattedValue & "</" & Name & ">"
    End Function

    Public Shared Function GenerateSitemap(ByVal SitemapUrlCollection As IEnumerable(Of SitemapUrl)) As String
        Dim mySitemapEnumerator As IEnumerator(Of SitemapUrl)
        Dim mySitemapStringBuilder As New StringBuilder()

        mySitemapStringBuilder.AppendLine(XMLTag)
        mySitemapStringBuilder.AppendLine(HeaderTag)

        mySitemapEnumerator = SitemapUrlCollection.GetEnumerator()

        If mySitemapEnumerator IsNot Nothing Then
            While mySitemapEnumerator.MoveNext
                mySitemapStringBuilder.AppendLine(AddSitemapUrl(mySitemapEnumerator.Current))
            End While
        End If

        mySitemapStringBuilder.AppendLine(ClosingHeaderTag)

        Return mySitemapStringBuilder.ToString
    End Function

End Class

